package tools

import (
	"gorm.io/gorm"
	"reflect"
	"strings"
)

// UpdateNonZeroFields 更新非 nil 字段，带 default 的字段会使用默认值更新
func UpdateNonZeroFields(db *gorm.DB, model interface{}) error {
	typ := reflect.TypeOf(model).Elem()
	val := reflect.ValueOf(model).Elem()

	updates := map[string]interface{}{}

	for i := 0; i < typ.NumField(); i++ {
		field := typ.Field(i)
		value := val.Field(i)

		// 获取 gorm tag
		gormTag := field.Tag.Get("gorm")
		if gormTag == "" || gormTag == "-" {
			continue
		}

		// 提取 column 名字
		columnName := ""
		tags := strings.Split(gormTag, ";")
		hasDefault := false

		for _, tag := range tags {
			tag = strings.TrimSpace(tag)
			if strings.HasPrefix(tag, "column:") {
				columnName = strings.TrimPrefix(tag, "column:")
			}
			if tag == "default" || strings.HasPrefix(tag, "default:") {
				hasDefault = true
			}
		}

		if columnName == "" {
			columnName = field.Name // 默认字段名作为列名
		}

		// 如果字段是指针类型
		if value.Kind() == reflect.Ptr {
			if value.IsNil() {
				// 如果字段是 nil，并且有 default，就更新为 default 值
				if hasDefault {
					// 注意：这里无法直接获取到 default 的具体值（因为 tag 只有 default 或 default:'0'），只能标记为更新
					// GORM 会在执行 Updates 时自动使用数据库默认值
					updates[columnName] = gorm.Expr("DEFAULT") // 告诉 GORM 使用数据库默认值
				}
				continue
			}

			// 非 nil，正常更新
			updates[columnName] = value.Elem().Interface()
		} else {
			// 非指针类型字段（比如 int、string 等）
			if isZero(value.Interface()) {
				continue
			}
			updates[columnName] = value.Interface()
		}
	}

	return db.Model(model).Updates(updates).Error
}

// isZero 判断一个值是否是零值（适用于基本类型）
func isZero(i interface{}) bool {
	v := reflect.ValueOf(i)
	switch v.Kind() {
	case reflect.String:
		return v.String() == ""
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return v.Int() == 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return v.Uint() == 0
	case reflect.Bool:
		return !v.Bool()
	default:
		return false
	}
}
